﻿using System;
using System.Configuration;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web.UI;
using CRMCommon;
using CRMCommon.DataSets;
using DevExpress.Web.ASPxScheduler;
using DevExpress.XtraScheduler;
using DevExpress.Web.ASPxClasses;

public partial class Main : Page
{
    #region Members

    private readonly Controller _controller = new Controller();
    
    #endregion

    #region Event Handlers

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack && !IsCallback)
            Setup();
        
        SetConnectionString();
        SetupMappings();
        SetupResources();
        FleetASPxGridView.DataSource = _controller.GetFleet(ASPxScheduler.ActiveView.GetVisibleIntervals().Start, ASPxScheduler.ActiveView.GetVisibleIntervals().End);
        FleetASPxGridView.DataMember = "Frota";
        SetClientDataView("");
        DataBind();
    }

    private void SetConnectionString()
    {
        _controller.SetupConnection(ConfigurationManager.AppSettings["FonteDados"], ConfigurationManager.AppSettings["NomeBaseDados"], ConfigurationManager.AppSettings["User"], ConfigurationManager.AppSettings["Password"]);
    }

    #endregion    

    #region Private Methods

    private void SetupMappings()
    {
        var mappings = ASPxScheduler.Storage.Appointments.Mappings;
        ASPxScheduler.Storage.BeginUpdate();
        try
        {
            mappings.AppointmentId = "Id";
            mappings.Start = "StartTime";
            mappings.End = "EndTime";
            mappings.Subject = "Subject";
            mappings.AllDay = "AllDay";
            mappings.Description = "Description";
            mappings.Label = "Label";
            mappings.Location = "Location";
            mappings.RecurrenceInfo = "RecurrenceInfo";
            mappings.ReminderInfo = "ReminderInfo";
            mappings.ResourceId = "OwnerId";
            mappings.Status = "Status";
            mappings.Type = "EventType";
            ASPxScheduler.Storage.Appointments.CustomFieldMappings.Add(new AppointmentCustomFieldMapping("ClientId", "ClientId"));
            ASPxScheduler.Storage.Appointments.CustomFieldMappings.Add(new AppointmentCustomFieldMapping("ContactId", "ContactId"));
        }
        finally
        {
            ASPxScheduler.Storage.EndUpdate();
        }
    }

    private void SetupResources()
    {
        ASPxScheduler.Storage.BeginUpdate();
        try
        {
            foreach (var funcionarioRow in _controller.GetEmployees().Funcionario)
                ASPxScheduler.Storage.Resources.Add(new Resource(funcionarioRow.Id, funcionarioRow.Nome));
        }
        finally 
        {
            ASPxScheduler.Storage.EndUpdate();
        }
    }

    private void Setup()
    {
        ASPxScheduler.Start = DateTime.Today;
    }

    private void SetClientDataView(string filter)
    {
        ClienteDataSet clients = _controller.GetClients(filter);
        foreach (ClienteDataSet.ClienteRow client in clients.Cliente)
        {
            if (!client.IsFotografiaNull())
                client.Fotografia = ResizeImage(client.Fotografia);
            else
            {
                string imageUrl = "Images\\DefaultClient.gif";
                Image image = Image.FromFile(Server.MapPath(imageUrl));
                MemoryStream dataStream = new MemoryStream();
                image.Save(dataStream, ImageFormat.Gif);
                client.Fotografia = dataStream.ToArray();
            }
        }
        ClientsASPxDataView.DataSource = clients;
        ClientsASPxDataView.DataMember = "Cliente";
        DataBind();
    }

    private byte[] ResizeImage(byte[] source)
    {
        try
        {
            Image imageSource = Image.FromStream(new MemoryStream(source));
            Bitmap originalImage = new Bitmap(imageSource);
            if (originalImage.Width <= 64 && originalImage.Height <= 64)
                return source;
            Bitmap bitmap = new Bitmap(64, 64);
            using (System.Drawing.Graphics graphic = Graphics.FromImage(bitmap))
            {
                float scaleFactor = originalImage.Width > originalImage.Height
                                        ?
                                            (float) 60/originalImage.Width
                                        : (float) 60/originalImage.Height;
                var widthInPixels = (float) (originalImage.Width*scaleFactor);
                var heightInPixels = (float) (originalImage.Height*scaleFactor);
                graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

                graphic.DrawImage(originalImage, 0, 0, widthInPixels, heightInPixels);

                MemoryStream dataStream = new MemoryStream();
                bitmap.Save(dataStream, ImageFormat.Png);
                return dataStream.ToArray();
            }
        }
        catch(Exception)
        {
            return source;
        }
    }


    #endregion

    #region Event Handlers

    protected void AppointmentObjectDataSource_ObjectCreated(object sender, System.Web.UI.WebControls.ObjectDataSourceEventArgs e)
    {
        SetConnectionString();
        var occurences = (CustomEventDataSource)e.ObjectInstance;
        foreach (var row in _controller.GetSchedule().Agenda)
            occurences.Events.Add(new CustomEvent { Id = row.Id, StartTime = row.DataInicio, EndTime = row.DataFim, Description = row.Nome, OwnerId = row.IdFuncionario, ClientId = row.IsIdClienteNull() ? null : (int?)row.IdCliente, ContactId = row.IsIdContactoNull() ? null : (int?)row.IdContacto });
    }
    
    protected void AppointmentObjectDataSource_Selecting(object sender, System.Web.UI.WebControls.ObjectDataSourceSelectingEventArgs e)
    {
    }
    
    protected void AppointmentObjectDataSource_Selected(object sender, System.Web.UI.WebControls.ObjectDataSourceStatusEventArgs e)
    {
    }
    
    protected void HistoryASPxGridView_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
    {
        int occurenceId;
        if (!Int32.TryParse(e.Parameters, out occurenceId))
            return;
        HistoryASPxGridView.DataSource = _controller.GetHistory(occurenceId);
        HistoryASPxGridView.DataMember = "Historico";
        HistoryASPxGridView.DataBind();
    }
    
    protected void ASPxScheduler_AppointmentFormShowing(object sender, AppointmentFormEventArgs e)
    {
        e.Container = new AppointmentFormTemplateContainer(ASPxScheduler);
    }
    
    protected void ASPxScheduler_BeforeExecuteCallbackCommand(object sender, SchedulerCallbackCommandEventArgs e)
    {
        if (e.CommandId == SchedulerCallbackCommandId.AppointmentSave)
            e.Command = new ScheduleAppointmentFormSaveCallbackCommand((ASPxScheduler)sender);
    }
    
    protected void ASPxScheduler_AppointmentInserting(object sender, PersistentObjectCancelEventArgs e)
    {
        var storage = (ASPxSchedulerStorage)sender;
        var appointment = (Appointment)e.Object;
        _controller.Insert(appointment.Start, appointment.End, Int32.Parse(appointment.ResourceId.ToString()), appointment.Subject, null, null);
        ASPxScheduler.DataBind();
        storage.RefreshData();
    }
    
    protected void ClientDataViewCallbackPanel_Callback(object sender, CallbackEventArgsBase e)
    {
        SetClientDataView(e.Parameter);
    }

    #endregion

    public string GetClientInstanceName(int index, string type)
    {
        return type.Equals("Panel") ? "DataViewPanel_" + index : "EditClientButton_" + index;
    }
}
